package com.ouc.eddyAlgorithm.service;

import com.ouc.common.entity.FlowData;
import com.ouc.common.entity.NcGridData;
import com.ouc.visualization.entity.ContourData;
import com.ouc.visualization.entity.FactorCondition;
import org.springframework.lang.Nullable;
import ucar.ma2.InvalidRangeException;
import ucar.nc2.NetcdfFile;

import java.io.IOException;
import java.util.concurrent.ExecutionException;

/**
 * 要素可视化服务层
 *
 * @author B504
 */
public interface FactorAlgorithmService {
  public ContourData<NcGridData> getContourData(NetcdfFile ncFile, String variableName, Float[] lon, Float[] lat, Integer depth) throws Exception;

  /**
   * 获取 nc 等值线数据。默认 0 层数据
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @return 返回nc等值线数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  ContourData<NcGridData> getNcContourData(NetcdfFile ncFile, String variableName) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 等值线数据
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param depth        深度层级
   * @return 返回nc等值线数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  ContourData<NcGridData> getNcContourData(NetcdfFile ncFile, String variableName, @Nullable Integer depth) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 等值线数据（有限制条件）。默认 0 层
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件
   * @param lat          纬度限制条件
   * @return 返回nc等值线数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  ContourData<NcGridData> getNcContourData(NetcdfFile ncFile, String variableName, @Nullable Float[] lon, @Nullable Float[] lat) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 等值线数据（有限制条件）。
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param lon          经度限制条件
   * @param lat          纬度限制条件
   * @param depth        深度层级
   * @return 返回nc等值线数据
   * @throws IOException
   * @throws InvalidRangeException
   */
  ContourData<NcGridData> getNcContourData(NetcdfFile ncFile, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer depth) throws IOException, InvalidRangeException;

  /**
   * 获取 nc 等值线数据（有限制条件）。
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param lon          经度限制
   * @param lat          纬度限制
   * @param depth        深度
   * @param time         时间
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  ContourData<NcGridData> getNcContourData(NetcdfFile ncFile, String variableName, @Nullable Float[] lon, @Nullable Float[] lat, @Nullable Integer depth, Integer time) throws IOException, InvalidRangeException;


  /**
   * 生成深度对应txt
   *
   * @param ncFile   nc文件
   * @param filePath txt文件绝对路径
   * @throws IOException
   * @throws InvalidRangeException
   */
  public void writeLevelMeter(NetcdfFile ncFile, String filePath) throws IOException, InvalidRangeException;

  /**
   * 获取限制经纬度的粒子流数据
   *
   * @param ncFile       nc文件
   * @param lonStart     开始经度
   * @param lonEnd       结束经度
   * @param latStart     开始纬度
   * @param latEnd       结束纬度
   * @param level        层级
   * @param variableName 变量名（只有uu和vv两种选项）
   * @param dilution     稀释倍数
   * @param exaggerate   夸大倍数（粒子流扩大效果显示更好）
   * @param reverseFlag  纬度是否从小到大，如果是需要翻转，否则不需要
   * @param startByZero  经度是否从0开始
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  public FlowData getParticleFlowDataOfFlowByLimit(NetcdfFile ncFile, float lonStart, float lonEnd, float latStart, float latEnd, Integer level, String variableName, int dilution, int exaggerate, boolean reverseFlag, boolean startByZero) throws IOException, InvalidRangeException;

  /**
   * 获取有经纬度和层级限制的粒子流
   *
   * @param ncFile       nc文件
   * @param lonStart     开始经度
   * @param lonEnd       结束经度
   * @param latStart     开始纬度
   * @param latEnd       结束纬度
   * @param level        层级
   * @param time         时间
   * @param variableName 变量名
   * @param dilution     稀释倍数
   * @param exaggerate   夸大倍数（粒子流扩大效果显示更好）
   * @param reverseFlag  纬度是否从小到大，如果是需要翻转，否则不需要
   * @param startByZero  经度是否从0开始
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  public FlowData getParticleFlowDataOfFlowByLimit(NetcdfFile ncFile, float lonStart, float lonEnd, float latStart, float latEnd, Integer level, Integer time, String variableName, int dilution, int exaggerate, boolean reverseFlag, boolean startByZero) throws IOException, InvalidRangeException;

  /**
   * 获取有经纬度和层级限制的风场粒子流
   *
   * @param ncFile       nc文件
   * @param lonStart     开始经度
   * @param lonEnd       结束经度
   * @param latStart     开始纬度
   * @param latEnd       结束纬度
   * @param level        层级
   * @param time         时间
   * @param variableName 变量名
   * @param dilution     稀释倍数
   * @param exaggerate   夸大倍数（粒子流扩大效果显示更好）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  public FlowData getParticleFlowDataOfFlowByLimitWind(NetcdfFile ncFile, float lonStart, float lonEnd, float latStart, float latEnd, Integer level, Integer time, String variableName, int dilution, int exaggerate) throws IOException, InvalidRangeException;

  /**
   * 获取限制经纬度的粒子流数据
   * 做实验使用
   *
   * @param ncFile       nc文件
   * @param lonStart     开始经度
   * @param lonEnd       结束经度
   * @param latStart     开始纬度
   * @param latEnd       结束纬度
   * @param level        层级
   * @param variableName 变量名（只有uu和vv两种选项）
   * @param dilution     稀释倍数
   * @param exaggerate   夸大倍数（粒子流扩大效果显示更好）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  public FlowData getParticleFlowDataOfFlowByLimit1(NetcdfFile ncFile, float lonStart, float lonEnd, float latStart, float latEnd, int level, String variableName, int dilution, int exaggerate) throws IOException, InvalidRangeException;

  /**
   * 获取一整层的粒子流数据
   *
   * @param ncFile       nc文件
   * @param level        层级
   * @param variableName 变量名（只有uu和vv两种）
   * @param dilution     稀释倍数
   * @param exaggerate   夸大倍数（粒子流扩大效果显示更好）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  public FlowData getParticleFlowDataOfFlowOfSlice(NetcdfFile ncFile, int level, String variableName, int dilution, int exaggerate) throws IOException, InvalidRangeException;

  /**
   * 获取经过经纬度限制条件的粒子流数据
   * 适用于没有u和v但是有总值和角度值
   *
   * @param ncFile       nc文件
   * @param lonStart     开始经度
   * @param lonEnd       结束经度
   * @param latStart     开始纬度
   * @param latEnd       结束纬度
   * @param level        层级
   * @param time         时间
   * @param variableName 变量名（应该说明是属于u数据还是v数据）
   * @param dilution     稀释倍数
   * @param exaggerate   夸张倍数（让粒子流更好看）
   * @param flagRadian   是否是弧度值
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */
  public FlowData getParticleFlowDataOfWaveOfLimit(NetcdfFile ncFile, float lonStart, float lonEnd, float latStart, float latEnd, Integer level, Integer time, String variableName, int dilution, int exaggerate, boolean flagRadian) throws IOException, InvalidRangeException;

  /**
   * 获取经过经纬度限制条件的粒子流数据
   * 适用于没有u和v但是有总值和角度值
   *
   * @param ncFile       nc文件
   * @param lonStart     开始经度
   * @param lonEnd       结束经度
   * @param latStart     开始纬度
   * @param latEnd       结束纬度
   * @param level        层级
   * @param variableName 变量名（应该说明是属于u数据还是v数据）
   * @param dilution     稀释倍数
   * @param exaggerate   夸张倍数（让粒子流更好看）
   * @param flagRadian   是否是弧度值
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   */

  public FlowData getParticleFlowDataOfWaveOfLimit(NetcdfFile ncFile, float lonStart, float lonEnd, float latStart, float latEnd, Integer level, String variableName, int dilution, int exaggerate, boolean flagRadian) throws IOException, InvalidRangeException;

  /**
   * 将文件路径中的nc文件加入到缓存中去
   *
   * @param filePath        nc文件
   * @param factorCondition 要素条件
   * @param dilution        稀释倍数
   * @param exaggerate      缩放倍数
   */

  void getVideoFromTime(String[] filePath, FactorCondition factorCondition, Integer dilution, Integer exaggerate, Integer time) throws IOException, InvalidRangeException;

  /**
   * 获取要素数据放到缓存里面
   * 由于前台已经写了多次访问接口
   * apiFox测试过没有问题
   * 所以只能先闲置
   *
   * @param filePath        文件路径
   * @param factorCondition 要素条件
   * @param time            时间
   * @throws IOException
   * @throws InvalidRangeException
   */
  void getFactorForCache(String filePath, FactorCondition factorCondition, Integer time) throws IOException, InvalidRangeException;

  /**
   * 通过获取常规nc数据要素获取bufferImage和min和max
   * 用于传给前台贴图
   *
   * @param ncFile          nc文件
   * @param factorCondition 要素条件
   * @param fixedMin        设定最小值
   * @param fixedMax        设定最大值
   * @param colorType       颜色类型
   * @param time            时间
   * @param reverseFlag     是否翻转（由纬度趋势决定）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ExecutionException
   * @throws InterruptedException
   */
  Object[] getCommonFactorForPict(NetcdfFile ncFile, FactorCondition factorCondition, float fixedMin, float fixedMax, String colorType, Integer time, boolean reverseFlag) throws IOException, InvalidRangeException, ExecutionException, InterruptedException;

  /**
   * 获取全球的常规数据
   * 全球分四块数据分别绘制
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param fixedMin     设定最小值
   * @param fixedMax     设定最大值
   * @param colorType    颜色类型
   * @param level        层级
   * @param time         时间
   * @param reverseFlag  是否翻转
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ExecutionException
   * @throws InterruptedException
   */
  Object[] getCommonFactorForPict(NetcdfFile ncFile, String variableName, float fixedMin, float fixedMax, String colorType, Integer level, Integer time, boolean reverseFlag) throws IOException, InvalidRangeException, ExecutionException, InterruptedException;

  /**
   * 通过获取常规nc数据要素获取bufferImage和min和max
   * 用于传给前台贴图
   * 这是对于流数据贴图
   *
   * @param ncFile          nc文件
   * @param factorCondition 要素设置条件
   * @param fixedMin        设置最小值
   * @param fixedMax        设置最大值
   * @param colorType       颜色类型
   * @param time            时间
   * @param reverseFlag     是否翻转（由纬度趋势决定）
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ExecutionException
   * @throws InterruptedException
   */
  Object[] getCurrentFactorForPict(NetcdfFile ncFile, FactorCondition factorCondition, float fixedMin, float fixedMax, String colorType, Integer time, boolean reverseFlag) throws IOException, InvalidRangeException, ExecutionException, InterruptedException;

  /**
   * 获取全球海流数据
   * 绘制图片
   *
   * @param ncFile      nc文件
   * @param fixedMin    设定的最小值
   * @param fixedMax    设定的最大值
   * @param colorType   颜色类型
   * @param level       层级
   * @param time        时间
   * @param reverseFlag 图片是否翻转
   * @return 图片流和每个图片的范围
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ExecutionException
   * @throws InterruptedException
   */
  Object[] getCurrentFactorForPict(NetcdfFile ncFile, float fixedMin, float fixedMax, String colorType, Integer level, Integer time, boolean reverseFlag) throws IOException, InvalidRangeException, ExecutionException, InterruptedException;

  /**
   * 绘制全球图片
   * 使用多线程生成，之所以不是所有都用多线程，是因为多线程并不一定比单线程快
   * 因为要考虑线程的切换
   *
   * @param ncFile       nc文件
   * @param variableName 变量名
   * @param fixedMin     设定的最小值
   * @param fixedMax     设定的最大值
   * @param colorType    颜色类型
   * @param level        层级
   * @param time         时间
   * @param reverseFlag  是否翻转
   * @return
   * @throws IOException
   * @throws InvalidRangeException
   * @throws ExecutionException
   * @throws InterruptedException
   */
  Object[] getGlobelPng(NetcdfFile ncFile, String variableName, float fixedMin, float fixedMax, String colorType, Integer level, Integer time, boolean reverseFlag) throws IOException, InvalidRangeException, ExecutionException, InterruptedException;
}
